<?php

namespace App\Exports;

use Illuminate\Support\Arr;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;

class StockingExport extends DefaultValueBinder implements FromArray, WithHeadings, WithMapping, WithCustomValueBinder
{
    use Exportable;

    private $commodityActivities;

    private $attributes = [];

    public function __construct($commodityActivities)
    {
        $this->commodityActivities = $commodityActivities;

        activity()
            ->on($this->commodityActivities)
            ->by(\Auth::user())
            ->withProperty('ip', app('request')->ip())
            ->log(sprintf('导出 %s (%s) 备货单', $this->commodityActivities['name'] ?? '', $this->commodityActivities['numbering'] ?? ''));
    }

    public function headings(): array
    {
        $this->commodityActivities->attributes->each(fn($attribute) => $this->attributes[] = [
            'id' => $attribute['id'],
            'name' => $attribute['name']
        ]);

        return array_merge(
            [
                '活动编号',
                '商品名称',
                '商品编号',
            ],
            array_column($this->attributes, 'name'), // 规格
            [
                '销售量',
                '发布量',
                '库存',
                '发货量',
                '成本价',
                '总金额',
            ]);
    }

    public function map($row): array
    {
        $values = arrayCombineByKey($row['values'] ?? [], 'attribute_id');

        return array_merge(
            [
                $row['numbering'] ?? ($this->commodityActivities['numbering'] ?? ''),
                $row['name'] ?? ($this->commodityActivities->commodity['name'] ?? ''),
                $row['commodity_numbering'] ?? ($this->commodityActivities->commodity['numbering'] ?? ''),
            ],
            array_map(fn($attribute) => $values[$attribute['id']]['content'] ?? '', $this->attributes),
            [
                $row['sales'] ?? 0,
                ($row['sales'] + $row['stock']) ?? 0,
                $row['stock'] ?? 0,
                $row['shipment'] ?? 0,
                isset($row['purchase_price']) ? number_format($row['purchase_price'] / 100, 2) : '',
                number_format(($row['total_amount'] ?? 0) / 100, 2),
            ]
        );
    }

    public function array(): array
    {
        $skus = $this->commodityActivities->skus->toArray();

        // 业务需要, 根据第一个 SKU 归拢
        $temp = [];
        foreach ($skus as $item) {
            $values = array_values(Arr::sort($item['values'], 'attribute_id'));
            $temp[$values[0]['content']][] = $item;
        }
        $tempSku = [];
        $salesTotal = 0; // 销售量总和
        $stockTotal = 0; // 库存总和
        $shipmentTotal = 0; // 发货量总和
        $amountTotal = 0; // 总金额
        foreach ($temp as $attributeId => $tempItem) {
            foreach ($tempItem as $_item) {
                $_item['total_amount'] = $_item['shipment'] * $_item['purchase_price']; // 总金额得在这里算好, 也只有这样才能在这一步骤得出总金额合计
                $tempSku[] = $_item;

                $salesTotal += $_item['sales'];
                $stockTotal += $_item['stock'];
                $shipmentTotal += $_item['shipment'];
                $amountTotal += $_item['total_amount'];
            }
        }

        // 最后一列 合计
        $tempSku[] = [
            'numbering' => '合计',
            'name' => '',
            'commodity_numbering' => '',
            'sales' => $salesTotal,
            'stock' => $stockTotal,
            'shipment' => $shipmentTotal,
            'total_amount' => $amountTotal,
        ];

        return $tempSku;
    }
}
